package com.accenture.automation.common;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.SSLContext;

import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class ApiClientUtil {
	private static final Logger log = LoggerFactory.getLogger(ApiClientUtil.class);

	private String url;

	/** 格式类型 application/json */
	private String contentType;

	/** 编码类型charset */
	private String charset;

	/** 传送的数据，json */
	private String postData = "";

	/** 传送的数据，json */
	private String getData = "";

	private boolean isHttps = true;
	private int socketTimeout = 1200;
	private int connectTimeout = 1200;

	/** http请求的Header */
	private List<Header> headers = new ArrayList<Header>();

	public void setPostData(String postData) {
		this.postData = postData;
	}

	public String getPostData() {
		return postData;
	}

	public String getGetData() {
		return getData;
	}

	public void setGetData(String getData) {
		this.getData = getData;
	}

	public ApiClientUtil(String url) {
		this.url = url;
		this.contentType = "application/json;charset=UTF-8";
		this.charset = "UTF-8";
	}

	public List<Header> getHeaders() {
		return headers;
	}

	public void setHeaders(List<Header> headers) {
		this.headers.addAll(headers);
	}

	// 添加Header
	public void addHeader(Header header) {
		this.headers.add(header);
	}

	// 发送post请求，无参数
	public String post() throws Exception {
		return post(this.postData);
	}

	// 发送post请求，有参数
	public String post(String postData) {
		String result = "";
		try {
			this.postData = postData;
			CloseableHttpClient httpclient = createHttpClient();
			HttpResponse response = httpclient.execute(buildPostMethod());
			result = EntityUtils.toString(response.getEntity(), "UTF-8");
			log.info(this.url + "【post】:" + postData + "/n" + "【result】:" + result);
		} catch (Exception e) {
			result = e.getMessage();
			log.info(this.url + "【post】:" + postData + "/n" + "【result】:" + e.getMessage());
		}
		return result;
	}

	public String postParam(Map<String, String> params) throws Exception {
		log.info(this.url + "【post】:" + JSON.toJSONString(params));
		CloseableHttpClient httpclient = createHttpClient();
		HttpResponse response = httpclient.execute(buildPostMethodForm(params));
		String result = EntityUtils.toString(response.getEntity(), "UTF-8");
		log.info("【result】:" + result);
		return result;
		// return EntityUtils.toString(response.getEntity());
	}

	//
	// 发送get请求，无参数
	public String get() throws Exception {
		return get(this.getData);
	}

	public String get(String getData) throws Exception {
		this.getData = getData;
		log.info(this.url + "[get]:" + getData);
		CloseableHttpClient httpclient = createHttpClient();
		HttpResponse response = httpclient.execute(buildGetMethod(getData));
		String result = EntityUtils.toString(response.getEntity(), "UTF-8");
		log.info("[result]:" + result);
		return result;
	}

	private CloseableHttpClient createHttpClient() throws Exception {
		CloseableHttpClient httpclient = null;
		if (this.isHttps) {
			SSLContext sslcontext = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy())
					.build();
			// sslcontext = new
			// SSLContextBuilder().loadTrustMaterial(file,password).build();
			// 只允许使用TLSv1协议
			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
			httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
		} else {
			httpclient = HttpClients.createDefault();
		}
		return httpclient;
	}

	private HttpPost buildPostMethod() {
		HttpPost method = new HttpPost(this.url);
		bulidHeader(method);
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout) // 设置传输超时时间
				.setConnectTimeout(connectTimeout).build();// 设置请求超时时间
		method.setConfig(requestConfig);
		if (this.postData != null) {
			method.setEntity(buildEntity(this.postData));
		}
		return method;
	}

	private HttpPost buildPostMethodForm(Map<String, String> params) throws UnsupportedEncodingException {
		HttpPost method = new HttpPost(this.url);
		bulidHeader(method);
		RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout) // 设置传输超时时间
				.setConnectTimeout(connectTimeout).build();// 设置请求超时时间
		method.setConfig(requestConfig);
		if (params.size() > 0) {
			method.setEntity(buildEntityForm(params));
		}
		return method;
	}

	private HttpGet buildGetMethod(String param) {
		HttpGet method = new HttpGet(this.url + "?" + param);
		return method;
	}

	private void bulidHeader(HttpRequestBase method) {
		if (this.headers != null && this.headers.size() > 0) {
			for (Header header : headers) {
				method.addHeader(header);
			}
		}
	}

	private StringEntity buildEntity(String postData) {
		StringEntity result = new StringEntity(postData, this.charset);// 解决中文乱码问题
		result.setContentEncoding(this.charset);
		result.setContentType(contentType);
		return result;
	}

	private UrlEncodedFormEntity buildEntityForm(Map<String, String> params) throws UnsupportedEncodingException {
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();
		Set<String> keySet = params.keySet();
		for (String key : keySet) {
			nvps.add(new BasicNameValuePair(key, params.get(key)));
		}
		@SuppressWarnings("unused")
		HttpPost method = new HttpPost(this.url);
		UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nvps, "UTF-8");
		return urlEncodedFormEntity;
	}

	// get 参数为params
	public String getParam(Map<String, String> params) throws Exception {
		log.info(this.url + "[get]:" + JSON.toJSONString(params));
		CloseableHttpClient httpclient = createHttpClient();
		HttpResponse response = httpclient.execute(buildGetMethodForm(params));
		String result = EntityUtils.toString(response.getEntity(), "UTF-8");
		log.info("[result]:" + result);
		return result;
	}

	/**
	 * 构建GetMethodForm
	 * 
	 * @param params
	 * @return
	 * @throws Exception
	 */
	private HttpGet buildGetMethodForm(Map<String, String> params) throws Exception {
		UrlEncodedFormEntity urlEncodedFormEntity = buildEntityForm(params);
		String str = "";
		str = EntityUtils.toString(urlEncodedFormEntity);
		HttpGet method = new HttpGet(this.url + "?" + str);
		bulidHeader(method);
		return method;

	}

}
